﻿#include <iostream>
#include <vector>

using namespace std;

class Component
{
public:
    Component(string & name)
    {
        m_name = name;
    }

    virtual ~Component(){}

    virtual void Add(const Component * com ) {};
    virtual void Remove(const Component * com) {};
    virtual void Display(int depth) {};
    virtual Component* getChild(int index)
    {
        return 0;
    }
    
    string & GetName()
    {
        return m_name;
    }
protected:
    string m_name;
};

class Leaf : public Component
{
public:
    Leaf(string& name) : Component(name) { }
    virtual ~Leaf(){}

    void Display(int depth)
    {
        if (depth < 0)
        {
            return;
        }

        string tmp(depth, '-');
        cout << tmp;
        cout  << m_name << endl;
    }
};

class Compsite :public Component
{
public:
    Compsite(string& name) :Component(name) { }

    virtual ~Compsite() 
    {
        cout << "start release :" << GetName() << endl;
        vector<Component*>::iterator tmp;
		for (vector<Component*>::iterator it = m_com.begin();
            it != m_com.end();) 
        {
            tmp = it;
            cout << "release :" << (*tmp)->GetName() << endl;
            it++;
			delete* tmp;
        }
        cout << "end release :" << GetName() << endl;
    }

    void Add(Component* com)
    {
        m_com.push_back(com);
    }

    void Remove(Component* com)
    {
        vector<Component*>::iterator it;
        it = find(m_com.begin(), m_com.end(), com);
        if (it != m_com.end())
        {
            m_com.erase(it);
        }

    }

    void Display(int depth)
    {
        if (depth < -1)
        {
            return;
        }

        string tmp(depth, '-');
        cout << tmp;
        cout << m_name << endl;
        for (vector<Component*>::iterator it = m_com.begin();
            it != m_com.end(); it++)
        {
            (* it)->Display(depth+2);
        }
    }
private:
    vector<Component*> m_com;
};

int main()
{
    string root = "root";
    Compsite* pRoot = new Compsite(root);
    string leafa = "leaf A";
    Leaf* pLeaf1 = new Leaf(leafa);
    string leafb = "leaf B";
    Leaf* pLeaf2 = new Leaf(leafb);
    pRoot->Add((Component*)pLeaf1);
    pRoot->Add((Component*)pLeaf2);

    string LayerOne = "Compsite X";
    Compsite* pLayer1 = new Compsite(LayerOne);
    string leafxa = "leaf XA";
    Leaf* pLeafxa = new Leaf(leafxa);
    string leafxb = "leaf XB";
    Leaf* pLeafxb = new Leaf(leafxb);
    pLayer1->Add((Component*)pLeafxa);
    pLayer1->Add((Component*)pLeafxb);
    pRoot->Add(pLayer1);

    string LayerTwo = "Compsite XY";
    Compsite* pLayer2 = new Compsite(LayerTwo);
    string leafxya = "leaf XYA";
    Leaf* pLeafxya = new Leaf(leafxya);
    string leafxyb = "leaf XYB";
    Leaf* pLeafxyb = new Leaf(leafxyb);
    pLayer2->Add((Component*)pLeafxya);
    pLayer2->Add((Component*)pLeafxyb);
    pLayer1->Add(pLayer2);

    string leafc = "leafc";
    Leaf* pLeafc = new Leaf(leafc);
    pRoot->Add(pLeafc);

    pRoot->Display(1);

    delete pRoot;
    return 0;
}


